#!/usr/bin/env python

import os
import csv

csv.register_dialect('lcead', delimiter='\t', quoting=csv.QUOTE_MINIMAL)

Name = 'Name'
Designator = 'Designator'
Footprint = 'Footprint'
Quantity = 'Quantity'
ManufacturerPart = 'Manufacturer Part'
SupplierPart = 'Supplier Part'
Price = 'Price'
Pins = 'Pins'

ENCODING = 'utf-16'

PerfixChar = 'a'

def test(file_name):
    with open(file_name, newline='', encoding=ENCODING) as csvfile:
        csvfile.seek(2)
        reader = csv.DictReader(csvfile, dialect='lcead')
        print(reader.fieldnames)
        for row in reader:
            print(', '.join(row.keys()))
            return

def getPerfixStr(perfixID):
    return chr(ord(PerfixChar) + perfixID) + ':'

def designatorAddPerfixID(row, perfixID):
    perfixStr = getPerfixStr(perfixID)
    designator = row[Designator]
    newDesignatorList = [perfixStr + dsg  for dsg in designator.split(',')]
    row[Designator] = ','.join(newDesignatorList)

def decode(file_name, fileID):
    rows = []
    fieldnames = []
    with open(file_name, newline='', encoding=ENCODING) as csvfile:
        reader = csv.DictReader(csvfile, dialect='lcead')
        fieldnames = reader.fieldnames.copy()
        for row in reader:
            designatorAddPerfixID(row, fileID)
            rows.append(row)
    return rows, fieldnames

def encode(outputFileName, rows, fieldnames):
    with open(outputFileName, 'w', newline='') as csvfile:
        writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
        writer.writeheader()
        for row in rows:
            writer.writerow(row)

def merge_row(baseRow, newRow):
    baseRow[Designator] += ',' + newRow[Designator]
    baseQuantity = int(baseRow[Quantity])
    newQuantity = int(newRow[Quantity])
    baseRow[Quantity] = str(baseQuantity + newQuantity)

def merge_rows(baseRows, newRows, simple=True):
    if len(baseRows) == 0 or simple:
        for row in newRows:
            baseRows.append(row)
    else:
        for newRow in newRows:
            existInRows1 = False
            newRowName = newRow[Name]
            newRowSupplierPart = newRow.get(SupplierPart)
            for baseRow in baseRows:
                if newRowName == baseRow[Name] and newRowSupplierPart == baseRow.get(SupplierPart):
                    existInRows1 = True
                    merge_row(baseRow, newRow)
                    break
            if not existInRows1:
                baseRows.append(newRow)
    return baseRows

def fileNameToBoardName(fileName):
    if "_BCR2100_" in fileName:
        board = "主板"
    elif "_BCR2100-Camera_" in fileName:
        board = "摄像头"
    elif "_BCR2100-Encoder_" in fileName:
        board = "编码器板"
    elif "_BCR2100-Front_" in fileName:
        board = "插座板"
    elif "_BCR2100-LCD_" in fileName:
        board = "LCD转接板"
    elif "_BCR2100-Printer_" in fileName:
        board = "打印板"
    elif "_BCR2100-Scanner_" in fileName:
        board = "光头转换板"
    elif "_BCR2100-Touch_" in fileName:
        board = "加样检测板"
    elif "_BCR2100-Other_" in fileName:
        board = "其它"
    else:
        board = fileName
    return board

def merge_files(csvfiles):
    global_rows = []
    global_fieldnames = []
    fileID = 0
    for csvfile in csvfiles:
        rows, fieldnames = decode(csvfile, fileID)
        #print(fieldnames)
        print('{} {}'.format(getPerfixStr(fileID), fileNameToBoardName(csvfile)))
        if len(global_fieldnames) == 0:
            global_fieldnames = fieldnames
        elif fieldnames != global_fieldnames:
            print('Not The Same Fieldnames!')
        merge_rows(global_rows, rows, False)
        fileID += 1
    return global_rows, global_fieldnames

if __name__ == '__main__':
    import sys
    import time
    #file_name = 'BOM_BCR2100-Touch_2021-12-05.csv'
    #test(file_name)
    #exit()

    if len(sys.argv) < 2:
        print('Usage:\n{} inFile1.csv inFile2.csv ... infileN.csv'.format(sys.argv[0]))
    else:
        output = "merge_{}.csv".format(time.strftime("%Y-%m-%d", time.localtime()))
        inputs = sys.argv[1:]
        rows, fieldnames = merge_files(inputs)
        encode(output, rows, fieldnames)